'''
Created on 23/ott/2009

@author: syn
'''
from utils.Environment import logger

import gtk
from utils import debug

class BaseListStore(gtk.GenericTreeModel):
    def __init__(self, entity_class, entities):
        gtk.GenericTreeModel.__init__(self)
        self.entity_class = entity_class
        self.columns = tuple(c.name for c in entity_class.table.columns)
        try:
            self.entities = entities()
        except TypeError:
            if entities and type(entities[0]) != entity_class:
                raise TypeError
            self.entities = entities
            
        self._path_iter_mapping()
            
        logger.debug("Creato list store con %s elementi" % str(len(self.entities)))
    
    def _path_iter_mapping(self):
        self.path_to_iter = dict([(e.id, i) for i, e in enumerate(self.entities)])
    
    def on_get_flags(self):
        return gtk.TREE_MODEL_LIST_ONLY | gtk.TREE_MODEL_ITERS_PERSIST
    
    def on_get_n_columns(self):
        return len(self.columns_type)
    
    def on_get_column_type(self, index):
        try:
            return self.columns_type[index]
        except IndexError:
            return None
    
    def on_get_iter(self, path):
        """
        The row reference is the id column of the table
        """
        if len(path) > 1: # This is because we are a list 
            return None
        try:
            return self.entities[path[0]].id
        except IndexError:
            return None

    def on_get_path(self, rowref):
        try:
            return self.path_to_iter[rowref]
        except KeyError: 
            return None
    
    def on_get_value(self, rowref, column):
        if column >= len(self.columns_type):
            return None
        try:
            path = self.path_to_iter[rowref]
            e = self.entities[path]
            return e.__getattribute__(self.columns[column])
        except KeyError:
            return None
        except IndexError:
            return None
        
    def on_iter_next(self, rowref):
        try:
            path = self.path_to_iter[rowref]
            return self.entities[path+1].id
        except:
            logger.debug("Iter Next Exception %s" % str(rowref))
        return None
        
    def on_iter_children(self, parent):
        """
        This model is a list, no child  
        """
        if parent:
            return None
        return self.entities[0].id
        
    def on_iter_has_child(self, rowref):
        return False
    
    def on_iter_n_children(self, rowref):
        if rowref:
            return 0
        return len(self.entities)
    
    def on_iter_nth_child(self, parent, n):
        if parent:
            return None
        try:
            return self.entities[n].id
        except IndexError:
            return None
        
    def on_iter_parent(self, child):
        return None
    
    def remove(self, iter):
        path = self.get_path(iter)
        logger.debug("row remove. path %d " % path)
        try:
            del self.entities[path[0]]
            self._path_iter_mapping()
            self.row_deleted(path)
        except:
            logger.debug("error on row remove")
    
    def add(self, entity):
        if not entity:
            return
        
        if type(entity) != self.entity_class:
            raise TypeError
        
        pos = len(self.entities)
        path = (pos,)
        self.entities.append(entity)
        self.path_to_iter[entity.id] = pos
        iter = self.get_iter(path)
        self.row_inserted(path,iter)
        # FIXME: must sort again entities array

    def get_entity(self, iter):
        try:
            path = self.get_path(iter)
            return self.entities[path[0]]
        except:
            return None
        
    def get_iter_by_entity(self, entity):
        if type(entity) != self.entity_class:
            return None
        
        try:
            path = (self.path_to_iter[entity.id],)
            iter = self.get_iter(path)
            return iter
        except:
            return None

class AuthorListStore(BaseListStore):
    def __init__(self, entity_class, entities=[]):
        self.columns_type = (long, str, str)
        BaseListStore.__init__(self, entity_class, entities)
    
class UserListStore(BaseListStore):
    def __init__(self, entity_class, entity_query):
        self.columns_type = (long, str, str, str, str, str, bool, str)
        BaseListStore.__init__(self, entity_class, entity_query)

class AddressListStore(BaseListStore):
    def __init__(self, entity_class, entity_query):
        self.columns_type = (long, str, str, str, str, str, str, str)
        BaseListStore.__init__(self, entity_class, entity_query)
        
class BookListStore(BaseListStore):
    def __init__(self, entity_class, entity_query):
        self.columns_type = (long, str, str)
        BaseListStore.__init__(self, entity_class, entity_query)
        
class GenreListStore(BaseListStore):
    def __init__(self, entity_class, entities=[]):
        self.columns_type = (long, str, str)
        BaseListStore.__init__(self, entity_class, entities)
        
class BookshopListStore(BaseListStore):
    def __init__(self, entity_class, entities=[]):
        self.columns_type = (long, str, str, str)
        BaseListStore.__init__(self, entity_class, entities)
        
class ProductListStore(BaseListStore):
    def __init__(self, entity_class, entities=[]):
        self.columns_type = (long, str, str, int, float, int, float)
        BaseListStore.__init__(self, entity_class, entities)
        
    def on_get_value(self, rowref, column):
        if column == 6:
            path = self.path_to_iter[rowref]
            e = self.entities[path]
            return e.discount
                
        return BaseListStore.on_get_value(self, rowref, column)
        
class EditionListStore(BaseListStore):
    def __init__(self, entity_class, entities=[]):
        self.columns_type = (long, str, str)
        BaseListStore.__init__(self, entity_class, entities)
        
class OrderListStore(BaseListStore):
    def __init__(self, entity_class, entities=[]):
        self.columns_type = (long, str, str, str, float)
        BaseListStore.__init__(self, entity_class, entities)
        
    def on_get_value(self, rowref, column):
        if column == 1:
            path = self.path_to_iter[rowref]
            e = self.entities[path]
            return e.bookshop
                
        return BaseListStore.on_get_value(self, rowref, column)